export class DomTool {
  /**
   * 获取窗口的内部宽高(并排除滚动条)
   * @returns
   */
  getViewSize(win: Window = window) {
    return {
      width: win.document.documentElement.clientWidth,
      height: win.document.documentElement.clientHeight
    }
  }

  /**
   * 根据类型自动转换高度
   * @param height
   * @returns
   */
  parseHeight(height: number | string) {
    if (typeof height === 'number') {
      return height
    }
    if (typeof height === 'string') {
      if (/^\d+(?:px)?$/.test(height)) {
        return Number.parseInt(height, 10)
      } else {
        return height
      }
    }
    return null
  }

  /**
   * 获取 top 属性值
   * @param elem dom
   * */
  getTop(elem: any): any {
    return elem.offsetTop + ((elem.offsetParent && this.getTop(elem.offsetParent)) || 0)
  }

  /**
   * 获取 left 属性值
   * @param elem dom
   * */
  getLeft(elem: any): any {
    return elem.offsetLeft + ((elem.offsetParent && this.getLeft(elem.offsetParent)) || 0)
  }

  /**
   * 事件绑定
   * @param elem dom
   * @param events 事件
   * @param handler 事件回调
   * */
  on(elem: any, events: any, handler: any) {
    ;[].concat(events).forEach((event) => elem.addEventListener(event, handler, false))
  }

  /**
   * 事件解除
   * @param elem dom
   * @param events 事件
   * @param handler 事件回调
   * */
  off(elem: any, events: any, handler: any) {
    ;[].concat(events).forEach((event) => elem.removeEventListener(event, handler, false))
  }

  /**
   * 单次事件
   * @param elem dom
   * @param events 事件
   * @param handler 事件回调
   * */
  once(elem: any, events: any, handler: any) {
    const listener = function (_this: any, args: any) {
      handler.apply(_this, args)
      _this.off(elem, events, listener)
    }
    this.on(elem, events, listener)
  }
}
